package gl.java.umsp.match;

import gl.java.pattern.ChainOfResponse;
import gl.java.umsp.ErrCode;
import gl.java.umsp.bean.Match;
import gl.java.umsp.bean.MatchResult;
import gl.java.umsp.bean.Room;
import gl.java.umsp.bean.User;
import lombok.extern.slf4j.Slf4j;

/**
 * 处理玩家的匹配事件,寻找合适的匹配算法,返回玩家匹配到的Room.
 * <p><b>使用synchronized修饰match方法.禁止多线程造成房间分配异常<b/></p>
 */
@Slf4j
public class MatchHandler extends ChainOfResponse<IMatch> implements IMatch {
    private InRoomUserMap mInRoomUserMap = new InRoomUserMap();

    @Override
    public void match(final Match match, final IMatchedCallBack listener) {
        log.info("Match Event:" + match);

        //不在线的用户直接返回.
        User user = match.getWantToMatchUser();

        if (user == null) {
            log.warn("match fail : match.wantToMatchUser not be find from  UserOnlineMap." + match + ", is not login!");
            listener.onMatched(MatchResult.createFailMatchResult(ErrCode.NotLogin,0));
            return;
        }
        //已经匹配到房间中的用户这把从旧房间剔除
        Room inMatching = mInRoomUserMap.isInMatching(user.userID);
        if (inMatching != null) {
            log.info("match repeat : user " + user.userID + " want to changed  a new room. the old room is:" + inMatching);
            mInRoomUserMap.remove(user.userID);
        }

        boolean isMatched = false;
        //使用一个代理做善后工作
        IMatchedCallBack afterMatch = new IMatchedCallBack() {
            @Override
            public void onMatched(MatchResult result) {
                if (result.isSuccess) {
                    mInRoomUserMap.put(result.room, result.wantToMatchUser);
                }
                listener.onMatched(result);
            }
        };
        //执行匹配过程
        for (IMatch iMatch : handlerList) {
            if (iMatch.getMatchType() == match.getMatchType()) {
                iMatch.match(match, afterMatch);
                isMatched = true;
                break;
            }
        }
        //检查匹配结果
        if (!isMatched) {
            log.warn("match fail :  " + user.userID);
            listener.onMatched(MatchResult.createFailMatchResult(ErrCode.NotSupportMatchType,user.userID));
        } else {
            log.info("match success");
        }
    }

    @Override
    public int getMatchType() {
        int type = 0;
        for (IMatch iMatch : handlerList) {
            type |= iMatch.getMatchType();
        }
        return type;
    }

    public void removeAll() {
        handlerList.clear();
    }


}
